﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using UIOC.CodeAnalysis.Helpers;

namespace UIOC.CodeAnalysis.Extensions;

internal static class NamedTypeSymbolExtensions {

    private static void LogInfo(string message) {
        SourceOutputHelper.LogInfo(DiagnosticSeverity.Info, $"[{nameof(NamedTypeSymbolExtensions)}] {message}");
    }

    /// <summary>
    /// 从接口提取泛型约束（Roslyn 4.3.1兼容）
    /// </summary>
    public static List<TypeParameterConstraintClauseSyntax> GetConstraintClauses(this INamedTypeSymbol typeSymbol) {
        var clauses = new List<TypeParameterConstraintClauseSyntax>();
        if (typeSymbol == null) {
            return clauses;
        }

        foreach (var typeParam in typeSymbol.TypeParameters) {
            // 创建约束子句（如 where T : ...）
            var clause = SyntaxFactory.TypeParameterConstraintClause(typeParam.Name);

            var constraints = new List<TypeParameterConstraintSyntax>();

            // 处理 class 约束
            if (typeParam.HasReferenceTypeConstraint) {
                constraints.Add(SyntaxFactory.ClassOrStructConstraint(SyntaxKind.ClassConstraint));
            }
            // 处理 struct 约束
            else if (typeParam.HasValueTypeConstraint) {
                constraints.Add(SyntaxFactory.ClassOrStructConstraint(SyntaxKind.StructConstraint));
            }

            // 处理 类型 约束
            if (typeParam.ConstraintTypes.Length > 0) {
                foreach (var constraintType in typeParam.ConstraintTypes) {
                    constraints.Add(SyntaxFactory.TypeConstraint(constraintType.CreateSimpleNameSyntax()));
                }
            }

            // 处理 new() 约束
            if (typeParam.HasConstructorConstraint) {
                constraints.Add(SyntaxFactory.ConstructorConstraint());
            }

            // 添加约束到子句
            if (constraints.Any()) {
                clause = clause.AddConstraints([.. constraints]);
                clauses.Add(clause);
            }
        }

        return clauses;
    }

    /// <summary>
    /// 获取类型的短名称，支持：
    /// - 非泛型类型（如 IData）
    /// - 未绑定泛型（如 IData<,>）
    /// - 已绑定泛型（如 IData<T, int>、IData<T>、IData<int>）
    /// - 嵌套泛型（如 IData<List<T>, Dictionary<string, int>>）
    /// </summary>
    public static string GetShortName(this INamedTypeSymbol typeSymbol, bool isUseUnboundName = false) {
        if (typeSymbol == null) {
            return string.Empty;
        }

        // 非泛型类型直接返回名称
        if (!typeSymbol.IsGenericType && !typeSymbol.IsUnboundGenericType) {
            return typeSymbol.Name;
        }

        // 处理未绑定泛型类型（泛型定义）
        if (typeSymbol.IsUnboundGenericType) {
            var typeParams = Enumerable.Range(1, typeSymbol.Arity)
                .Select(i => isUseUnboundName ? typeSymbol.TypeParameters[i].Name : string.Empty);
            return $"{typeSymbol.Name}<{string.Join(", ", typeParams)}>";
        }

        // 处理已绑定泛型类型（泛型实例）
        if (typeSymbol.IsGenericType) {
            var typeArgs = typeSymbol.TypeArguments
                .Select(arg => arg.GetTypeArgumentShortName());
            return $"{typeSymbol.Name}<{string.Join(", ", typeArgs)}>";
        }

        return typeSymbol.Name;
    }

    // 收集所有未实现的抽象成员（包括父类）
    public static IEnumerable<ISymbol> GetUnimplementedAbstractMembers(this INamedTypeSymbol classSymbol) {
        var current = classSymbol.BaseType;
        while (current != null && current.SpecialType != SpecialType.System_Object) {
            foreach (var member in current.GetMembers().Where(m => m.IsAbstract)) {
                // 如果当前类没有实现该成员
                if (!classSymbol.GetMembers().Any(m => SymbolEqualityComparer.Default.Equals(m, member)) &&
                    !classSymbol.AllInterfaces.SelectMany(i => i.GetMembers()).Any(m => SymbolEqualityComparer.Default.Equals(m, member))) {
                    yield return member;
                }
            }
            current = current.BaseType;
        }
    }
}
